#ifndef __CORE_FUNC_H__
#define __CORE_FUNC_H__
#if 1
#include "core_cm.h"

static __INLINE uint32_t __get_CONTROL(void)
{
  register uint32_t __regControl __ASM("control");
  return (__regControl);
}

static __INLINE void __set_CONTROL(uint32_t control)
{
  register uint32_t __regControl __ASM("control");
  __regControl = control;
}

static __INLINE uint32_t __get_IPSR(void)
{
  register uint32_t __regIPSR __ASM("ipsr");
  return (__regIPSR);
}

static __INLINE uint32_t __get_APSR(void)
{
  register uint32_t __regAPSR __ASM("apsr");
  return (__regAPSR);
}

static __INLINE uint32_t __get_xPSR(void)
{
  register uint32_t __regXPSR __ASM("xpsr");
  return (__regXPSR);
}

static __INLINE uint32_t __get_PSP(void)
{
  register uint32_t __regProcessStackPointer __ASM("psp");
  return (__regProcessStackPointer);
}

static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
  register uint32_t __regProcessStackPointer __ASM("psp");
  __regProcessStackPointer = topOfProcStack;
}

static __INLINE uint32_t __get_MSP(void)
{
  register uint32_t __regMainStackPointer __ASM("msp");
  return (__regMainStackPointer);
}

static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
  register uint32_t __regMainStackPointer __ASM("msp");
  __regMainStackPointer = topOfMainStack;
}

static __INLINE uint32_t __get_PRIMASK(void)
{
  register uint32_t __regPriMask __ASM("primask");
  return (__regPriMask);
}

static __INLINE void __set_PRIMASK(uint32_t priMask)
{
  register uint32_t __regPriMask __ASM("primask");
  __regPriMask = (priMask);
}

#if (__CORTEX_M >= 0x03)
/**
    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
    Can only be executed in Privileged modes.
 */
#define __enable_fault_irq __enable_fiq

/**
    This function disables FIQ interrupts by setting the F-bit in the CPSR.
    Can only be executed in Privileged modes.
 */
#define __disable_fault_irq __disable_fiq

/**
    This function returns the current value of the Base Priority register.
 */
static __INLINE uint32_t __get_BASEPRI(void)
{
  register uint32_t __regBasePri __ASM("basepri");
  return (__regBasePri);
}

/**
    This function assigns the given value to the Base Priority register.
 */
static __INLINE void __set_BASEPRI(uint32_t basePri)
{
  register uint32_t __regBasePri __ASM("basepri");
  __regBasePri = (basePri & 0xff);
}

/**
    This function returns the current value of the Fault Mask register.
 */
static __INLINE uint32_t __get_FAULTMASK(void)
{
  register uint32_t __regFaultMask __ASM("faultmask");
  return (__regFaultMask);
}

/**
    This function assigns the given value to the Fault Mask register.
 */
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
  register uint32_t __regFaultMask __ASM("faultmask");
  __regFaultMask = (faultMask & (uint32_t)1);
}

#endif /* (__CORTEX_M >= 0x03) */

#if (__CORTEX_M == 0x04)

/**
    This function returns the current value of the Floating Point Status/Control register.
 */
static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  register uint32_t __regfpscr __ASM("fpscr");
  return (__regfpscr);
#else
  return (0);
#endif
}

/** Set FPSCR
    This function assigns the given value to the Floating Point Status/Control register.
 */
static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  register uint32_t __regfpscr __ASM("fpscr");
  __regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */

#if (__CORTEX_M >= 0x03)
__attribute__((always_inline)) static __INLINE void __enable_irq(void)
{
  __ASM volatile("cpsie i");
}

__attribute__((always_inline)) static __INLINE void __disable_irq(void)
{
  __ASM volatile("cpsid i");
}

__attribute__((always_inline)) static __INLINE uint32_t __get_CONTROL(void)
{
  uint32_t result;

  __ASM volatile("MRS %0, control"
                 : "=r"(result));
  return (result);
}

__attribute__((always_inline)) static __INLINE void __set_CONTROL(uint32_t control)
{
  __ASM volatile("MSR control, %0"
                 :
                 : "r"(control));
}

__attribute__((always_inline)) static __INLINE uint32_t __get_IPSR(void)
{
  uint32_t result;

  __ASM volatile("MRS %0, ipsr"
                 : "=r"(result));
  return (result);
}

__attribute__((always_inline)) static __INLINE uint32_t __get_APSR(void)
{
  uint32_t result;

  __ASM volatile("MRS %0, apsr"
                 : "=r"(result));
  return (result);
}

__attribute__((always_inline)) static __INLINE uint32_t __get_xPSR(void)
{
  uint32_t result;

  __ASM volatile("MRS %0, xpsr"
                 : "=r"(result));
  return (result);
}

__attribute__((always_inline)) static __INLINE uint32_t __get_PSP(void)
{
  register uint32_t result;

  __ASM volatile("MRS %0, psp\n"
                 : "=r"(result));
  return (result);
}

__attribute__((always_inline)) static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
  __ASM volatile("MSR psp, %0\n"
                 :
                 : "r"(topOfProcStack));
}

__attribute__((always_inline)) static __INLINE uint32_t __get_MSP(void)
{
  register uint32_t result;

  __ASM volatile("MRS %0, msp\n"
                 : "=r"(result));
  return (result);
}

__attribute__((always_inline)) static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
  __ASM volatile("MSR msp, %0\n"
                 :
                 : "r"(topOfMainStack));
}

__attribute__((always_inline)) static __INLINE uint32_t __get_PRIMASK(void)
{
  uint32_t result;

  __ASM volatile("MRS %0, primask"
                 : "=r"(result));
  return (result);
}

__attribute__((always_inline)) static __INLINE void __set_PRIMASK(uint32_t priMask)
{
  __ASM volatile("MSR primask, %0"
                 :
                 : "r"(priMask));
}

__attribute__((always_inline)) static __INLINE void __enable_fault_irq(void)
{
  __ASM volatile("cpsie f");
}

__attribute__((always_inline)) static __INLINE void __disable_fault_irq(void)
{
  __ASM volatile("cpsid f");
}

__attribute__((always_inline)) static __INLINE uint32_t __get_BASEPRI(void)
{
  uint32_t result;

  __ASM volatile("MRS %0, basepri_max"
                 : "=r"(result));
  return (result);
}

__attribute__((always_inline)) static __INLINE void __set_BASEPRI(uint32_t value)
{
  __ASM volatile("MSR basepri, %0"
                 :
                 : "r"(value));
}

__attribute__((always_inline)) static __INLINE uint32_t __get_FAULTMASK(void)
{
  uint32_t result;

  __ASM volatile("MRS %0, faultmask"
                 : "=r"(result));
  return (result);
}

__attribute__((always_inline)) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
  __ASM volatile("MSR faultmask, %0"
                 :
                 : "r"(faultMask));
}
#endif /* (__CORTEX_M >= 0x03) */

#if (__CORTEX_M == 0x04)
__attribute__((always_inline)) static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  uint32_t result;

  __ASM volatile("VMRS %0, fpscr"
                 : "=r"(result));
  return (result);
#else
  return (0);
#endif
}

__attribute__((always_inline)) static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  __ASM volatile("VMSR fpscr, %0"
                 :
                 : "r"(fpscr));
#endif
}
#endif /* (__CORTEX_M == 0x04) */

#endif
#endif